﻿using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using RabbitMQ.Client;

namespace IotS.Core.Helpers
{
    public class QueuePub : IDisposable
    {
        private readonly IConnection _connection;
        private readonly IModel _channel;
        private readonly bool _receive = false;

        public QueuePub(bool receive = false)
        {
            _receive = receive;
            var factory = new ConnectionFactory
            {
                HostName = ConfigHelper.Settings.RabbitMQ.Host,
                UserName = ConfigHelper.Settings.RabbitMQ.UserName,
                Password = ConfigHelper.Settings.RabbitMQ.Password,
                AutomaticRecoveryEnabled = true
            };

            _connection = factory.CreateConnection();
            _channel = _connection.CreateModel();

            var exchangeName = receive
                ? ConfigHelper.Settings.RabbitMQ.ExchangeName
                : ConfigHelper.Settings.RabbitMQ.SubExchangeName;
            var queueName = receive
                ? ConfigHelper.Settings.RabbitMQ.QueueName
                : ConfigHelper.Settings.RabbitMQ.SubQueueName;

            _channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout);
            _channel.QueueDeclare(queueName, true, false, true, null);
            _channel.QueueBind(queueName, exchangeName, "");
        }

        public void SendString(string message)
        {
            var exchangeName = _receive
                ? ConfigHelper.Settings.RabbitMQ.ExchangeName
                : ConfigHelper.Settings.RabbitMQ.SubExchangeName;

            var body = Encoding.UTF8.GetBytes(message ?? string.Empty);
            _channel.BasicPublish(ConfigHelper.Settings.RabbitMQ.ExchangeName, "", true, null, body);
            body = null;
        }

        public void SendTo<T>(T message)
        {
            var json = JsonConvert.SerializeObject(message);
            SendString(json);
        }

        public void Dispose()
        {
            if (_connection.IsOpen)
                _connection.Close();
            _connection.Dispose();
        }
    }
}
